package br.com.velp.sudecap.serviceimpl;

import br.com.velp.sudecap.comum.ValidationException;
import br.com.velp.sudecap.dao.DecretoDAO;
import br.com.velp.sudecap.dto.DecretoParametrosConsultaDTO;
import br.com.velp.sudecap.entidade.Decreto;
import br.com.velp.sudecap.enumerator.StatusDecretoEnum;
import br.com.velp.sudecap.service.DecretoService;
import br.com.velp.sudecap.web.util.MensagemUtil;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <sumario> <objetivo> "Rastreabilidade" </objetivo> <autor> EDUARDO SANTOS DE
 * OLIVEIRA </autor> <versao>1.0.0.0</versao> <data_criacao> 17.10.2012
 * </data_criacao> <data_ultima_alteracao> N/A </data_ultima_alteracao>
 * <requisitos_afetados> RF006.01 - Listar Decretos / RF006.02 - Cadastrar
 * Decretos </requisitos_afetados> <descricao> Implementação da Interface
 * Responsável Pelas Operações de CRUD Referentes ao Contexto de Decretos
 * </descricao> </sumario>
 */
@Service("decretoService")
@Transactional(readOnly = true)
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class DecretoServiceImpl implements DecretoService {

    public static final Long serialVersionUID = 1L;
    @Autowired
    private DecretoDAO decretoDAO;

    @Transactional(readOnly = false)
    @Override
    public Long salvar(Decreto decreto) throws ValidationException {
	validarDecreto(decreto);
	return this.decretoDAO.salvar(decreto);
    }

    @Transactional(readOnly = false)
    @Override
    public void atualizar(Decreto decreto) throws ValidationException {
	validarDecreto(decreto);
	this.decretoDAO.atualizar(decreto);
    }

    @Transactional(readOnly = false)
    @Override
    public void excluir(Decreto decreto) {
	this.decretoDAO.excluir(decreto);
    }

    @Override
    public Decreto obterPorId(Long idDecreto) {
	return this.decretoDAO.obterPorId(idDecreto);
    }

    @Override
    public int contarDecretos(DecretoParametrosConsultaDTO parametros) {
	return this.decretoDAO.contarDecretos(parametros);
    }

    @Override
    public List<Decreto> buscarDecretosPaginados(int firstResult, int maxResults,
	    DecretoParametrosConsultaDTO parametros, Order order) {
	List<Decreto> decretos = this.decretoDAO.buscarDecretosPaginados(
		firstResult, maxResults, parametros, order);
	for(Decreto decreto : decretos){
	    StatusDecretoEnum situacao = recuperarStatusDecreto(decreto);
	    decreto.setStatus(situacao != null ? situacao.getLabel() : "");
	}
	return decretos;
    }

    @Override
    public List<Decreto> recuperarDecretos(Long idDecretoFiltro, String numero) {
	return this.decretoDAO.recuperarDecretos(idDecretoFiltro, numero);
    }

    @Override
    public Decreto recuperarDecreto(Long id) {
	return this.decretoDAO.recuperarDecreto(id);
    }

    @Override
    public StatusDecretoEnum recuperarStatusDecreto(Decreto decreto) {

	StatusDecretoEnum statusDecreto = null;
	SimpleDateFormat sdf = new SimpleDateFormat(MensagemUtil.getMensagem("formatoPadraoData"));

	try {
	    if (decreto.getDecretoRevogado() != null) {
		statusDecreto = StatusDecretoEnum.REVOGADO;
	    } else if (decreto.getDataCaducacao() != null) {
		if (decreto.getDataCaducacao().before(sdf.parse(sdf.format(new Date())))) {
		    statusDecreto = StatusDecretoEnum.CADUCADO;
		} else {
		    statusDecreto = StatusDecretoEnum.EM_VIGOR;
		}
	    }
	} catch (Exception e) {
	    return null;
	}

	return statusDecreto;

    }

    private void validarDecreto(Decreto decreto) throws ValidationException {
	ValidationException ve = new ValidationException();
	if (this.decretoDAO.existeDecretoJaCadastrado(decreto)) {
	    ve.adicionarMensagem("decretoJaCadastradoComNumeroInformado");
	}
	if (ve.hasErros()) {
	    throw ve;
	}
    }
}
